今天我们来谈一下 Android 的 IPC 基础 Binder。
说起 IPC (inter-Process Communication , 进程间通信),在我的印象中是一个一直没有去触碰过的角落,因为实际项目中也并没有使用到,而且听说 IPC 特别麻烦和难,也就一直没有去了解。趁最近有空,我大慨看了一下,也了解了一点。在这里做一下笔记。
先贴一个地址,据说这篇文章是最硬核的底层分析没有之一!可惜我没怎么看懂。。
https://blog.csdn.net/universus/article/details/6211589
为什么是 Binder ?
Android 是基于 Linux 内核的操作系统,关于 IPC 这一块,Linux 已经有了解决方案,为什么 Android 还有另起炉灶呢?
在 Linux 中的 IPC 方式有 管道、System V IPC 、消息队列、共享内存/信号量、Socket 。既然有这么多选择,Android 为什么都不用呢?
性能
首先要考虑 Android 平台的特性,Android 是一个便携式设备的操作系统,这一点就要求 Android 必须考虑性能方面的问题,在数据传输过程中,Socket 、管道、消息队列 都需要拷贝两次,而 Binder 只需要拷贝一次,性能上更加具有优势。
便利
另一方面是 Android 设备上通常有许多传感器,而很多应用都需要这些传感器进行互相配合,这个就要求 Android 中的 IPC 需要更加灵活,简单。基于 Client-Server 的设计模式广泛应用于互联网和数据库访到嵌入式手持设备内部通信等各个方面,通过这种模式,可以给开发者提供很多便利,无需花过多的时间和精力就能获取到这些传感器的数据。而在 Linux 中,支持 Client-Server 的只有 Socket。由于 Socket 是通用型的 IPC 解决方案,性能上还是差了一些。
安全
Android 作为一个开放式的平台,有众多的开发者,安全性也是一个非常重要的指标。在传统的 IPC 中,没有任何安全措施,无法进行身份认证。而且传统的 IPC 访问接入点是开放的,访问的地址和文件名都是开放的,无法对恶意程序进行阻断。
所以基于以上的原因,Android 采用的是 Binder 的机制进行 IPC 通信。
Binder 通信模型
Binder 框架定义了四个角色:Server、Client、ServiceManager 以及 Binder 驱动。其中 Server、Client、ServiceManager 运行于用户空间,Binder 运行与内核空间。这四个角色跟互联网类似:Server 是服务器、Client 是客户端、ServiceManager 是DNS 、Binder 驱动是路由器。
Binder 驱动
和互联网中的路由器一般,虽然默默无闻,但却是通信的核心。虽然叫驱动,但是跟硬件去没有什么关系,只是由于它工作于内核态,负责进程间 Binder 间通信的建立,Binder 在进程之间的传递等一系列底层支持。
ServiceManager
ServiceManager 就像互联网中的 DNS 服务器一样,我们不需要知道具体的 Server 地址,我们只需要知道这个 Server 对应的名称就可以进行连接了。就像我们输入一个域名就可以访问到对应的网站一样。
想我们平时使用到的 getSystemService()
获取对应的服务,使用的也是通过 ServiceManager 获取到的。要使用 Servicemanager 获取到相应的 Server 就需要现在 ServiceManager 中进行注册,这个我们需要注册域名是一样的。
注册的时候,需要将 Binder 和 名称 以数据包的形式通过 Binder 驱动发送给 ServiceManager 进行注册,然后 ServiceManager 就会在内存中添加一个节点,并未这个节点添加这个 Binder 的引用。
Server
Server 中存在一个 Binder 用于提供服务。
Client
Client 通过获取到的 Binder 进行 IPC 通信。
其他
其他太底层的东西,现在还看不懂,也就不多 BB 了。